package storage.data;

import Transaction.Transaction;
import Common.ByteArray;
import Common.GlobalConst;

/*
 * usage: the very beginning of the file , containing the whole Information of the database;
 */
public class HeaderPage extends Page {
	public static int NEXT_PAGE = 0 ;
	public static int ENTRY_SIZE = 4 + GlobalConst.MAXDBNAME + 4 ;  // 2 for additional bit to store string
	public int X_ENTRY_POINT = 4 ;
	public int NUM_ENTRY = ( GlobalConst.PAGESIZE - X_ENTRY_POINT ) / ENTRY_SIZE  ;
	public String defTable = "SYSTEM" ; 
	
	public HeaderPage ( boolean needData ) {
		super( needData ) ;
	}
	
	public HeaderPage ( Page apage ) {
		super ( false ) ;
		data = apage.getData() ;
	}
	
	public PageID getNextPage () {
		try {
			return new PageID ( ByteArray.readInt(data, NEXT_PAGE)); 
		} catch  ( Exception e ) {
		}
		return INVALID_PAGE ;
	}
	
	public void  writeNextPage ( Transaction tx, PageID thisPage, PageID id ) {
		try{
			tx.set( defTable, thisPage, data, NEXT_PAGE, id.pageId ) ;
			dirtyBit = true ; 
			usedBit = true ;
		}catch ( Exception e ) {
			e.printStackTrace() ; 
		}
	}
	
	public NameEntry getEntry ( int entry ) {
		try {
			usedBit = true ;
			int pageNo = ByteArray.readInt( data, getEntryPoint() + ENTRY_SIZE * entry ) ;
			String name = ByteArray.readString( data , getEntryPoint()  + ENTRY_SIZE * entry +  4  );
			return new NameEntry ( name , new PageID ( pageNo )) ;
		}catch ( Exception e ) {
			return NameEntry.INVALID_DBNAME_ENTRY ; 
		}
	}
	
	public void writeEntry ( Transaction tx, PageID pid, int entry , NameEntry value  ) {
		try { 
			usedBit = true; 
			dirtyBit = true ;
			tx.set(defTable, pid, data, getEntryPoint()  + ENTRY_SIZE * entry ,value.firstPage.pageId, true ) ;
			tx.set(defTable, pid, data , getEntryPoint()  + ENTRY_SIZE * entry + 4 , value.name, true ) ;
		}catch ( Exception e) {
			System.out.println ( "Cannot write in entry " + value.name + " " + value.firstPage.pageId ) ; 
			e.printStackTrace() ; 
		}
	}
	
	protected int getEntryPoint () {
		return X_ENTRY_POINT ; 
	}

}
